home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / xlisp.lbr / XLOBJ.CQ / xlobj.c
Text File  |  1985-06-03  |  22KB  |  707 lines

  1.                       /* xlobj - xlisp object functions */
  2.  
  3. #ifdef CI_86
  4. #include "a:stdio.h"
  5. #include "xlisp.h"
  6. #endif
  7.  
  8.  
  9. #ifdef AZTEC
  10. #include "a:stdio.h"
  11. #include "xlisp.h"
  12. #endif
  13.  
  14.  
  15. #ifdef unix
  16. #include <stdio.h>
  17. #include <xlisp.h>
  18. #endif
  19.  
  20.  
  21.                              /* global variables */
  22.  
  23. struct node *self;
  24.  
  25.  
  26.                             /* external variables */
  27.  
  28. extern struct node *xlstack;
  29. extern struct node *xlenv;
  30.  
  31.  
  32.                               /* local variables */
  33.  
  34. static struct node *class;
  35. static struct node *object;
  36. static struct node *new;
  37. static struct node *isnew;
  38. static struct node *msgcls;
  39. static struct node *msgclass;
  40. static int varcnt;
  41.  
  42.  
  43.               /* instance variable numbers for the class 'Class' */
  44.  
  45. #define MESSAGES        0       /* list of messages */
  46. #define IVARS           1       /* list of instance variable names */
  47. #define CVARS           2       /* list of class variable names */
  48. #define CVALS           3       /* list of class variable values */
  49. #define SUPERCLASS      4       /* pointer to the superclass */
  50. #define IVARCNT         5       /* number of class instance variables */
  51. #define IVARTOTAL       6       /* total number of instance variables */
  52.  
  53.  
  54.             /* number of instance variables for the class 'Class' */
  55.  
  56. #define CLASSSIZE       7
  57.  
  58.  
  59.  
  60.         /* forward declarations (the extern hack is because of decusc) */
  61.  
  62. extern struct node *findmsg();
  63. extern struct node *findvar();
  64. extern struct node *defvars();
  65. extern struct node *makelist();
  66.  
  67.  
  68.                          /*****************************
  69.                          *  xlclass - define a class  *
  70.                          *****************************/
  71.  
  72. struct node *xlclass(name,vcnt)
  73.   char *name; int vcnt;
  74. {
  75.     struct node *sym,*cls;
  76.  
  77.     sym = xlenter(name);                    /* Create the class */
  78.     cls = sym->n_symvalue = newnode(OBJ);
  79.     cls->n_obclass = class;
  80.     cls->n_obdata = makelist(CLASSSIZE);
  81.  
  82.     if (vcnt > 0)                           /* Set instance var count */
  83.     {
  84.         (xlivar(cls,IVARCNT)->n_listvalue = newnode(INT))->n_int = vcnt;
  85.         (xlivar(cls,IVARTOTAL)->n_listvalue = newnode(INT))->n_int = vcnt;
  86.     }
  87.  
  88.     xlivar(cls,SUPERCLASS)->n_listvalue = object;     /* superclass = object */
  89.  
  90.     return (cls);
  91. }
  92.  
  93.  
  94.        /******************************************************************
  95.        *  xlmfind - find the message binding for a message to an object  *
  96.        ******************************************************************/
  97.  
  98. struct node *xlmfind(obj,msym)
  99.   struct node *obj,*msym;
  100. {
  101.     return (findmsg(obj->n_obclass,msym));
  102. }
  103.  
  104.  
  105.                    /******************************************
  106.                    *  xlxsend - send a message to an object  *
  107.                    ******************************************/
  108.  
  109. struct node *xlxsend(obj,msg,args)
  110.   struct node *obj,*msg,*args;
  111. {
  112.     struct node *oldstk,method,cptr,val,*isnewmsg,*oldenv;
  113.  
  114.     oldenv = xlenv;                         /* Save old environment */
  115.     oldstk = xlsave(&method,&cptr,&val,NULL);
  116.  
  117.     method.n_ptr = msg->n_msgcode;          /* Get method for this msg */
  118.     if (method.n_ptr->n_type != SUBR && method.n_ptr->n_type != LIST)
  119.         xlfail("bad method");
  120.  
  121.     xlbind(self,obj);                       /* Bind 'self' and 'msgclass' */
  122.     xlbind(msgclass,msgcls);
  123.  
  124.     if (method.n_ptr->n_type == SUBR)       /* Evaluate function */
  125.     {
  126.         xlfixbindings(oldenv);
  127.         val.n_ptr = (*method.n_ptr->n_subr)(args);
  128.     }
  129.     else
  130.     {                                       /* Bind formal arguments */
  131.         xlabind(method.n_ptr->n_listvalue,args);
  132.         xlfixbindings(oldenv);
  133.  
  134.         cptr.n_ptr = method.n_ptr->n_listnext;
  135.         while (cptr.n_ptr != NULL)
  136.             val.n_ptr = xlevarg(&cptr.n_ptr);
  137.     }
  138.  
  139.     xlunbind(oldenv);                       /* Restore environment */
  140.  
  141.     /* after creating an object, send it the "isnew" message */
  142.     if (msg->n_msg == new && val.n_ptr != NULL)
  143.     {
  144.         if ((isnewmsg = xlmfind(val.n_ptr,isnew)) == NULL)
  145.             xlfail("no method for the isnew message");
  146.         val.n_ptr = xlxsend(val.n_ptr,isnewmsg,args);
  147.     }
  148.  
  149.     xlstack = oldstk;                       /* Restore old stack frame */
  150.     return (val.n_ptr);
  151. }
  152.  
  153.  
  154.         /***************************************************************
  155.         *  xlsend - send a message to an object (message in arg list)  *
  156.         ***************************************************************/
  157.  
  158. struct node *xlsend(obj,args)
  159.   struct node *obj,*args;
  160. {
  161.     struct node *msg;
  162.  
  163.     if ((msg = xlmfind(obj,xlevmatch(SYM,&args))) == NULL)
  164.         xlfail("no method for this message");
  165.  
  166.     return (xlxsend(obj,msg,args));
  167. }
  168.  
  169.  
  170.     /***********************************************************************
  171.     *  xlobsym - find a class or instance variable for the current object  *
  172.     ***********************************************************************/
  173.  
  174. struct node *xlobsym(sym)
  175.   struct node *sym;
  176. {
  177.     struct node *obj;
  178.  
  179.     if ((obj = self->n_symvalue) != NULL && obj->n_type == OBJ)
  180.         return (findvar(obj,sym));
  181.     else
  182.         return (NULL);
  183. }
  184.  
  185.  
  186.                     /****************************************
  187.                     *  mnew - create a new object instance  *
  188.                     ****************************************/
  189.  
  190. static struct node *mnew()
  191. {
  192.     struct node *oldstk,obj,*cls;
  193.  
  194.     oldstk = xlsave(&obj,NULL);             /* New stack frame */
  195.  
  196.     cls = self->n_symvalue;                 /* Get class name */
  197.  
  198.     obj.n_ptr = newnode(OBJ);               /* Generate new object */
  199.     obj.n_ptr->n_obclass = cls;
  200.     obj.n_ptr->n_obdata = makelist(getivcnt(cls,IVARTOTAL));
  201.  
  202.     xlstack = oldstk;                       /* Restore old stack frame */
  203.     return (obj.n_ptr);
  204. }
  205.  
  206.  
  207.                       /************************************
  208.                       *  misnew - initialize a new class  *
  209.                       ************************************/
  210.  
  211. static struct node *misnew(args)
  212.   struct node *args;
  213. {
  214.     struct node *oldstk,super,*obj;
  215.  
  216.     oldstk = xlsave(&super,NULL);           /* Create new stack frame */
  217.  
  218.     if (args != NULL)                       /* Get superclass is present */
  219.         super.n_ptr = xlevmatch(OBJ,&args);
  220.     else
  221.         super.n_ptr = object;
  222.  
  223.     xllastarg(args);                        /* Check no more args */
  224.  
  225.     obj = self->n_symvalue;                 /* Get the object */
  226.     xlivar(obj,SUPERCLASS)->n_listvalue = super.n_ptr;
  227.     (xlivar(obj,IVARTOTAL)->n_listvalue = newnode(INT))->n_int =
  228.          getivcnt(super.n_ptr,IVARTOTAL);
  229.  
  230.     xlstack = oldstk;                       /* Restore stack frame */
  231.     return (obj);
  232. }
  233.  
  234.  
  235.                   /*******************************************
  236.                   *  xladdivar - enter an instance variable  *
  237.                   *******************************************/
  238.  
  239. xladdivar(cls,var)
  240.   struct node *cls; char *var;
  241. {
  242.     struct node *ivar,*lptr;
  243.  
  244.     ivar = xlivar(cls,IVARS);               /* Find 'ivars' instance var */
  245.  
  246.     lptr = newnode(LIST);                   /* add instance var */
  247.     lptr->n_listnext = ivar->n_listvalue;
  248.     ivar->n_listvalue = lptr;
  249.     lptr->n_listvalue = xlenter(var);
  250. }
  251.  
  252.  
  253.                     /****************************************
  254.                     *  entermsg - add a message to a class  *
  255.                     ****************************************/
  256.  
  257. static struct node *entermsg(cls,msg)
  258.   struct node *cls,*msg;
  259. {
  260.     struct node *ivar,*lptr,*mptr;
  261.  
  262.     ivar = xlivar(cls,MESSAGES);                 /* Find 'messages' iv */
  263.  
  264.     for (lptr = ivar->n_listvalue; lptr != NULL; lptr = lptr->n_listnext)
  265.         if ((mptr = lptr->n_listvalue)->n_msg == msg)
  266.             return (mptr);
  267.  
  268.     /* allocate a new message entry if one wasn't found */
  269.     lptr = newnode(LIST);
  270.     lptr->n_listnext = ivar->n_listvalue;
  271.     ivar->n_listvalue = lptr;
  272.     lptr->n_listvalue = mptr = newnode(LIST);
  273.     mptr->n_msg = msg;
  274.  
  275.     return (mptr);                               /* Return the symbol node */
  276. }
  277.  
  278.  
  279.              /*****************************************************
  280.              *  answer - define a method for answering a message  *
  281.              *****************************************************/
  282.  
  283. static struct node *answer(args)
  284.   struct node *args;
  285. {
  286.     struct node *oldstk,arg,msg,fargs,code;
  287.     struct node *obj,*mptr,*fptr;
  288.  
  289.     oldstk = xlsave(&arg,&msg,&fargs,&code,NULL);     /* New stack frame */
  290.     arg.n_ptr = args;
  291.  
  292.     msg.n_ptr = xlevmatch(SYM,&arg.n_ptr);       /* Message symbol */
  293.  
  294.     fargs.n_ptr = xlevmatch(LIST,&arg.n_ptr);    /* Formal arg list */
  295.     code.n_ptr = xlevmatch(LIST,&arg.n_ptr);     /* the code */
  296.     xllastarg(arg.n_ptr);                        /* End of args */
  297.  
  298.     obj = self->n_symvalue;                      /* Object node */
  299.     mptr = entermsg(obj,msg.n_ptr);              /* New message list entry */
  300.  
  301.     mptr->n_msgcode = fptr = newnode(LIST);      /* Set up message node */
  302.     fptr->n_listvalue = fargs.n_ptr;
  303.     fptr->n_listnext = code.n_ptr;
  304.  
  305.     xlstack = oldstk;                            /* Restore old stack frame */
  306.     return (obj);
  307. }
  308.  
  309.  
  310.               /***************************************************
  311.               *  mivars - define the list of instance variables  *
  312.               ***************************************************/
  313.  
  314. static struct node *mivars(args)
  315.   struct node *args;
  316. {
  317.     struct node *cls,*super;
  318.     int scnt;
  319.  
  320.     cls = defvars(args,IVARS);              /* Define list of ivs */
  321.  
  322.     if ((super = xlivar(cls,SUPERCLASS)->n_listvalue) != NULL)
  323.         scnt = getivcnt(super,IVARTOTAL);
  324.     else
  325.         scnt = 0;
  326.  
  327.     (xlivar(cls,IVARCNT)->n_listvalue = newnode(INT))->n_int = varcnt;
  328.     (xlivar(cls,IVARTOTAL)->n_listvalue = newnode(INT))->n_int = scnt+varcnt;
  329.  
  330.     return (cls);
  331. }
  332.  
  333.  
  334.  
  335.         /****************************************************************
  336.         *  getivcnt - get the number of instance variables for a class  *
  337.         ****************************************************************/
  338.  
  339. static int getivcnt(cls,ivar)
  340.   struct node *cls; int ivar;
  341. {
  342.     struct node *cnt;
  343.  
  344.     if ((cnt = xlivar(cls,ivar)->n_listvalue) != NULL)
  345.         if (cnt->n_type == INT)
  346.             return (cnt->n_int);
  347.         else
  348.             xlfail("bad value for instance variable count");
  349.     else
  350.         return (0);
  351. }
  352.  
  353.  
  354.  
  355.                 /************************************************
  356.                 *  mcvars - define the list of class variables  *
  357.                 ************************************************/
  358.  
  359. static struct node *mcvars(args)
  360.   struct node *args;
  361. {
  362.     struct node *cls;
  363.  
  364.     cls = defvars(args,CVARS);              /* define list of class vars */
  365.     xlivar(cls,CVALS)->n_listvalue = makelist(varcnt);     /* make new list */
  366.  
  367.     return (cls);
  368. }
  369.  
  370.  
  371.  
  372.             /*******************************************************
  373.             *  defvars - define a class or instance variable list  *
  374.             *******************************************************/
  375.  
  376. static struct node *defvars(args,varnum)
  377.   struct node *args; int varnum;
  378. {
  379.     struct node *oldstk,vars,*vptr,*cls,*sym;
  380.  
  381.     oldstk = xlsave(&vars,NULL);            /* Create new stack frame */
  382.     vars.n_ptr = xlevmatch(LIST,&args);     /* Get ivar list */
  383.     xllastarg(args);                        /* Last argument ! */
  384.  
  385.     cls = self->n_symvalue;                 /* Class node */
  386.  
  387.     varcnt = 0;                             /* Check each var in list */
  388.     for (vptr = vars.n_ptr;
  389.          vptr != NULL && vptr->n_type == LIST;
  390.          vptr = vptr->n_listnext)
  391.     {
  392.         /* make sure this is a valid symbol in the list */
  393.         if ((sym = vptr->n_listvalue) == NULL || sym->n_type != SYM)
  394.             xlfail("bad variable list");
  395.  
  396.         if (checkvar(cls,sym))              /* Check not already defined */
  397.             xlfail("multiply defined variable");
  398.         varcnt++;                           /* Count the variable */
  399.     }
  400.  
  401.     if (vptr != NULL)                       /* Check for correct end */
  402.         xlfail("bad variable list");
  403.  
  404.     xlivar(cls,varnum)->n_listvalue = vars.n_ptr;     /* Define new list */
  405.  
  406.     xlstack = oldstk;                       /* Restore old stack frame */
  407.     return (cls);
  408. }
  409.  
  410.  
  411.  
  412.                     /****************************************
  413.                     *  xladdmsg - add a message to a class  *
  414.                     ****************************************/
  415.  
  416. xladdmsg(cls,msg,code)
  417.   struct node *cls; char *msg; struct node *(*code)();
  418. {
  419.     struct node *mptr;
  420.  
  421.     mptr = entermsg(cls,xlenter(msg));      /* enter message selector */
  422.     mptr->n_msgcode = newnode(SUBR);        /* Store the method */.
  423.     mptr->n_msgcode->n_subr = code;
  424. }
  425.  
  426.  
  427.  
  428.                    /******************************************
  429.                    *  getclass - get the class of an object  *
  430.                    ******************************************/
  431.  
  432. static struct node *getclass(args)
  433.   struct node *args;
  434. {
  435.     xllastarg(args);                   /* Check no arguments */
  436.     return (self->n_symvalue->n_obclass);
  437. }
  438.  
  439.  
  440.  
  441.                          /******************************
  442.                          *  obprint - print an object  *
  443.                          ******************************/
  444.  
  445. static struct node *obprint(args)
  446.   struct node *args;
  447. {
  448.     xllastarg(args);                   /* Check no arguments */
  449.  
  450.     printf("<Object: #%o>",self->n_symvalue);
  451.     return (self->n_symvalue);
  452. }
  453.  
  454.  
  455.  
  456.              /******************************************************
  457.              *  obshow - show the instance variables of an object  *
  458.              ******************************************************/
  459.  
  460. static struct node *obshow(args)
  461.   struct node *args;
  462. {
  463.     xllastarg(args);                   /* Check no arguments */
  464.  
  465.     xlprint(self->n_symvalue->n_obdata,TRUE);
  466.     return (self->n_symvalue);
  467. }
  468.  
  469.  
  470.  
  471.                      /**************************************
  472.                      *  defisnew - default 'isnew' method  *
  473.                      **************************************/
  474.  
  475. static struct node *defisnew(args)
  476.   struct node *args;
  477. {
  478.     xllastarg(args);                   /* Check for null arg list */
  479.     return (self->n_symvalue);
  480. }
  481.  
  482.  
  483.  
  484.            /*********************************************************
  485.            *  sendsuper - send a message to an object's superclass  *
  486.            *********************************************************/
  487.  
  488. static struct node *sendsuper(args)
  489.   struct node *args;
  490. {
  491.     struct node *obj,*super,*msg;
  492.  
  493.     obj = self->n_symvalue;            /* Get the object and its super class */
  494.     super = xlivar(obj->n_obclass,SUPERCLASS)->n_listvalue;
  495.  
  496.                                        /* Find message binding */
  497.     if ((msg = findmsg(super,xlevmatch(SYM,&args))) == NULL)
  498.         xlfail("no method for this message");
  499.  
  500.     return (xlxsend(obj,msg,args));    /* and send it */
  501. }
  502.  
  503.  
  504.       /*******************************************************************
  505.       *  findmsg - find the message binding given an object and a class  *
  506.       *******************************************************************/
  507.  
  508. static struct node *findmsg(cls,sym)
  509.   struct node *cls,*sym;
  510. {
  511.     struct node *lptr,*msg;
  512.  
  513.     msgcls = cls;                           /* Start at specified class */
  514.     while (msgcls != NULL)                  /* Look for the message */
  515.     {
  516.         for (lptr = xlivar(msgcls,MESSAGES)->n_listvalue;
  517.              lptr != NULL;
  518.              lptr = lptr->n_listnext)
  519.             if ((msg = lptr->n_listvalue) != NULL && msg->n_msg == sym)
  520.                 return (msg);
  521.  
  522.         msgcls = xlivar(msgcls,SUPERCLASS)->n_listvalue;
  523.     }
  524.  
  525.     return (NULL);                          /* Message not found */
  526. }
  527.  
  528.  
  529.                 /************************************************
  530.                 *  findvar - find a class or instance variable  *
  531.                 ************************************************/
  532.  
  533. static struct node *findvar(obj,sym)
  534.   struct node *obj,*sym;
  535. {
  536.     struct node *cls,*lptr;
  537.     int base,varnum;
  538.     int found;
  539.  
  540.     cls = obj->n_obclass;                        /* Get class of object */
  541.     base = getivcnt(cls,IVARTOTAL);              /* Get number of ivs */
  542.  
  543.     found = FALSE;                               /* Find the var */
  544.     for (; cls != NULL; cls = xlivar(cls,SUPERCLASS)->n_listvalue)
  545.     {
  546.         if ((base -= getivcnt(cls,IVARCNT)) < 0)
  547.             xlfail("error finding instance variable");
  548.  
  549.         if (!found && cls == msgclass->n_symvalue)
  550.             found = TRUE;
  551.  
  552.         varnum = 0;                              /* Lookup the iv */
  553.         for (lptr = xlivar(cls,IVARS)->n_listvalue;
  554.              lptr != NULL;
  555.              lptr = lptr->n_listnext)
  556.             if (found && lptr->n_listvalue == sym)
  557.                 return (xlivar(obj,base + varnum));
  558.             else
  559.                 varnum++;
  560.  
  561.         if (!found)                              /* Skip class vars if found */
  562.             continue;
  563.  
  564.         varnum = 0;                              /* Lookup class vars */
  565.         for (lptr = xlivar(cls,CVARS)->n_listvalue;
  566.              lptr != NULL;
  567.              lptr = lptr->n_listnext)
  568.             if (lptr->n_listvalue == sym)
  569.                 return (xlcvar(cls,varnum));
  570.             else
  571.                 varnum++;
  572.     }
  573.  
  574.     return (NULL);                               /* Var not found */
  575. }
  576.  
  577.  
  578.         /****************************************************************
  579.         *  checkvar - check for an existing class or instance variable  *
  580.         ****************************************************************/
  581.  
  582. static int checkvar(cls,sym)
  583.   struct node *cls,*sym;
  584. {
  585.     struct node *lptr;
  586.  
  587.     for (; cls != NULL; cls = xlivar(cls,SUPERCLASS)->n_listvalue)
  588.     {
  589.         for (lptr = xlivar(cls,IVARS)->n_listvalue;   /* Lookup instance var */
  590.              lptr != NULL;
  591.              lptr = lptr->n_listnext)
  592.             if (lptr->n_listvalue == sym)
  593.                 return (TRUE);
  594.  
  595.         for (lptr = xlivar(cls,CVARS)->n_listvalue;   /* Lookup class var */
  596.              lptr != NULL;
  597.              lptr = lptr->n_listnext)
  598.             if (lptr->n_listvalue == sym)
  599.                 return (TRUE);
  600.     }
  601.  
  602.     return (FALSE);                                   /* Var not found */
  603. }
  604.  
  605.  
  606.                      /**************************************
  607.                      *  xlivar - get an instance variable  *
  608.                      **************************************/
  609.  
  610. struct node *xlivar(obj,num)
  611.   struct node *obj; int num;
  612. {
  613.     struct node *ivar;
  614.  
  615.     for (ivar = obj->n_obdata; num > 0; num--)   /* Get instance var */
  616.         if (ivar != NULL)
  617.             ivar = ivar->n_listnext;
  618.         else
  619.             xlfail("bad instance variable list");
  620.  
  621.     return (ivar);
  622. }
  623.  
  624.  
  625.                        /**********************************
  626.                        *  xlcvar - get a class variable  *
  627.                        **********************************/
  628.  
  629. struct node *xlcvar(cls,num)
  630.   struct node *cls; int num;
  631. {
  632.     struct node *cvar;
  633.  
  634.     for (cvar = xlivar(cls,CVALS)->n_listvalue; num > 0; num--)
  635.         if (cvar != NULL)
  636.             cvar = cvar->n_listnext;
  637.         else
  638.             xlfail("bad class variable list");
  639.  
  640.     return (cvar);
  641. }
  642.  
  643.  
  644.  
  645.                       /************************************
  646.                       *  makelist - make a list of nodes  *
  647.                       ************************************/
  648.  
  649. static struct node *makelist(cnt)
  650.     int cnt;
  651. {
  652.     struct node *oldstk,list,*lnew;
  653.  
  654.     oldstk = xlsave(&list,NULL);            /* Create a new stack frame */
  655.  
  656.     for (; cnt > 0; cnt--)                  /* Make the list */
  657.     {
  658.         lnew = newnode(LIST);
  659.         lnew->n_listnext = list.n_ptr;
  660.         list.n_ptr = lnew;
  661.     }
  662.  
  663.     xlstack = oldstk;                       /* Restore the old stack frame */
  664.     return (list.n_ptr);
  665. }
  666.  
  667.  
  668.              /*****************************************************
  669.              *  xloinit - object function initialization routine  *
  670.              *****************************************************/
  671.  
  672. xloinit()
  673. {
  674.     class = NULL;                           /* Dont confuse gc */
  675.     object = NULL;
  676.  
  677.     new = xlenter("new");                   /* Enter object realtaed symbols */
  678.     isnew = xlenter("isnew");
  679.     self = xlenter("self");
  680.     msgclass = xlenter("msgclass");
  681.  
  682.     class = xlclass("Class",CLASSSIZE);     /* Create 'Class' object */
  683.     class->n_obclass = class;
  684.  
  685.     object = xlclass("Object",0);           /* Create 'Object class */
  686.  
  687.     xlivar(class,SUPERCLASS)->n_listvalue = object;
  688.     xladdivar(class,"ivartotal");       /* ivar number 6 */
  689.     xladdivar(class,"ivarcnt");         /* ivar number 5 */
  690.     xladdivar(class,"superclass");      /* ivar number 4 */
  691.     xladdivar(class,"cvals");           /* ivar number 3 */
  692.     xladdivar(class,"cvars");           /* ivar number 2 */
  693.     xladdivar(class,"ivars");           /* ivar number 1 */
  694.     xladdivar(class,"messages");        /* ivar number 0 */
  695.     xladdmsg(class,"new",mnew);
  696.     xladdmsg(class,"answer",answer);
  697.     xladdmsg(class,"ivars",mivars);
  698.     xladdmsg(class,"cvars",mcvars);
  699.     xladdmsg(class,"isnew",misnew);
  700.  
  701.     xladdmsg(object,"class",getclass);
  702.     xladdmsg(object,"print",obprint);
  703.     xladdmsg(object,"show",obshow);
  704.     xladdmsg(object,"isnew",defisnew);
  705.     xladdmsg(object,"sendsuper",sendsuper);
  706. }
  707.